package com.ideaplugin.datamanager.config;

import cn.hutool.http.ContentType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * @author zjb
 * @date 18-3-20
 */
@Aspect()
@Component
@Slf4j
public class LogAdvice {

    @Autowired
    private ObjectMapper objectMapper;

    @Around("execution(* com.ideaplugin..*.controller..*.*(..))")
    public Object controllerAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        long serviceStartTime = System.currentTimeMillis();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        StringBuilder logInfo = new StringBuilder();
        logInfo.append("\nControllerName:");
        String methodName = joinPoint.getSignature().getName();
        logInfo.append(className).append(".").append(methodName);
        logInfo.append("\nrequestURI:" + MDC.get(MdcFilter.requestURI));
        logInfo.append("\nparams:");
        final HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (Objects.equals(request.getMethod(), HttpMethod.GET.name())) {
            logInfo.append(request.getQueryString());
        } else {
            if (request.getContentType().contains(ContentType.MULTIPART.getValue())) {
                final Object arg = joinPoint.getArgs()[0];
                if (arg instanceof MultipartFile) {
                    logInfo.append("文件名称：" + ((MultipartFile) arg).getOriginalFilename());
                }
            } else {
                logInfo.append(joinPoint.getArgs().length == 1 ? objectMapper.writeValueAsString(joinPoint.getArgs()[0]) : objectMapper.writeValueAsString(joinPoint.getArgs()));
            }
        }
        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Exception e) {
            logInfo.append("\nresult:[").append(result).append("]");
            logInfo.append("\nexception:[").append(e).append("]");
            long serviceEndTime = System.currentTimeMillis();
            long runtime = (serviceEndTime - serviceStartTime);
            logInfo.append("\ncosttime:").append(runtime).append("ms");
            //抛给全局异常处理打印错误日志
            log.error(logInfo.toString());
            throw e;
        }
        String resultJson = "";
        if (result != null) {
            resultJson = objectMapper.writeValueAsString(result);
        }
        logInfo.append("\nresult:[").append(resultJson).append("]");
        long serviceEndTime = System.currentTimeMillis();
        long runtime = (serviceEndTime - serviceStartTime);
        logInfo.append("\ncosttime:").append(runtime).append("ms");
        log.info(logInfo.toString());
        return result;
    }

}
